package main

import (
	"bytes"
	"crypto/ecdsa"
	"crypto/rand"
	"device/model"
	"device/util"
	"encoding/hex"
	"encoding/json"
	"encoding/pem"
	"flag"
	"fmt"
	"github.com/emmansun/gmsm/sm2"
	"github.com/emmansun/gmsm/smx509"
	"github.com/gogf/gf/v2/net/gtcp"
	"github.com/gogf/gf/v2/net/gudp"
	"github.com/gogf/gf/v2/util/grand"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"time"
)

// 已经授权的IP地址
var defaultUID = []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}
var ipAllow map[string]bool

func main() {
	GataWay := ""
	KeyCenter := ""
	etcd := flag.Bool("e", false, "是否etcd模式")
	flag.Parse()
	if *etcd == true {
		GataWay = util.GetGatawayLeader(etcdAddr)
		KeyCenter = util.GetKeyCenterLeader(etcdAddr)
		fmt.Println("GataWay:", GataWay, "KeyCenter", KeyCenter)
	} else {
		GataWay = "192.168.146.11:9000"
		KeyCenter = "192.168.146.12:8990"
	}
	//步驟1 ：发送资源获取请求
	//验证是否有了证书
	_, err2 := os.Stat("./key/private.pem")
	if err2 != nil { //无证书
		fmt.Println("无证书模式")
		fmt.Println("正在发送消息：TO", GataWay)
		conn, err := gudp.NewConn(GataWay)
		if err != nil {
			panic(err)
		}
		conn.Send(DeviceCer().ToBytes())

		//阻塞等待密钥中心密钥
		time.Sleep(2 * time.Second)
		m := &model.ClientPemRequestMessage{
			DeviceCer().ID,
			DeviceCer().Token,
			DeviceCer().Factory,
		}
		//	gtcp.SendRecvPkg(dao.KeyCenter, m.ToBytes())
		pkg, err := gtcp.SendRecv(KeyCenter, m.ToBytes(), -1)
		if err != nil {
			fmt.Println("err", err)
			fmt.Println("单包信息可能未能发送成功")
		}
		Key := new(model.Key)
		err = json.Unmarshal(pkg, Key)
		if err != nil {
			log.Println("json.Unmarshal err", err)
		}
		writePemFile(Key) //写证书
	}
	time.Sleep(5 * time.Second)
	//有证书了

	//生成单包信息
	spaPackage := NewSPAPackage()
	//生成单包信息映射，包括对单包信息进行加密，计算单包信息的消息摘要和对摘要进行签名
	hashMap := GenSPAHashMap(spaPackage)
	haspMap, err := json.Marshal(hashMap)
	if err != nil {
		panic(err)
	}
	//封装消息包
	DeviceSPAMsg := new(model.Device)
	DeviceSPAMsg.ID = DeviceCer().ID
	DeviceSPAMsg.Token = DeviceCer().Token
	DeviceSPAMsg.MessageType = model.SPA
	DeviceSPAMsg.Data = haspMap

	DeviceSPAMsgBytes, err := json.Marshal(DeviceSPAMsg)
	err = gudp.Send(GataWay, DeviceSPAMsgBytes)
	if err != nil {
		log.Println(err)
		return
	}
	//向网关发送单包信息
	fmt.Println(len(DeviceSPAMsgBytes))
	//
	fmt.Println("请求http服务")
	err = gudp.Send(GataWay, DeviceSPAMsgBytes)
	if err != nil {
		fmt.Println("gudp.Send err", err)
		return
	}
	//获取服务
	time.Sleep(2 * time.Second)
	_, p, err2 := util.SplitIPAndPort(GataWay)
	if err != nil {
		panic(err2)
	}
	getServer(p)
}

func Sign(data []byte) []byte {
	prKey, _ := ReadKeyFromFile(2)
	sign, err := prKey.Sign(rand.Reader, data, sm2.DefaultSM2SignerOpts)
	if err != nil {
		panic(err)
	}
	return sign
}

func writePemFile(key *model.Key) {
	priFile, err := os.Create("./key/private.pem")
	pubFile, err := os.Create("./key/public.pem")
	if err != nil {
		panic(err)
	}

	pubFile.Write(key.PUBKEY.Data)
	priFile.Write(key.PRIKEY.Data)
	return
}

func DeviceCer() *model.Device {
	m := new(model.Device)
	m.ID = 5
	m.Token = "cBmjRJUuorxlnghtSUpq"
	m.MessageType = model.Certificate
	return m
}

func TestFuckDevice() *model.Device {
	m := new(model.Device)
	m.ID = 1
	m.Token = grand.Letters(20)
	return m
}

// ReadKeyFromFile 从文件中读key，num为1只读公钥，num为2读公私钥
func ReadKeyFromFile(num int) (pr *ecdsa.PrivateKey, pu *ecdsa.PublicKey) {
	//pubFile := "./key/public.pem"
	//priFile := "./key/private.pem"
	//fmt.Println(GetGatawayIP())
	//fmt.Println(GetKeyCenterIP())
	pubF, err := os.Open("./key/public.pem")
	defer pubF.Close()
	if err != nil {
		panic(err)
	}

	if num == 2 {
		priF, err := os.Open("./key/private.pem")
		defer priF.Close()
		//解析私钥
		b1 := new(bytes.Buffer)
		io.Copy(b1, priF)
		decode1, _ := pem.Decode(b1.Bytes())
		prikey, err := smx509.ParsePKCS8PrivateKey(decode1.Bytes)
		if err != nil {
			panic(err)
		}
		pr = &prikey.(*sm2.PrivateKey).PrivateKey
	}
	//解析公钥
	b2 := new(bytes.Buffer)
	io.Copy(b2, pubF)
	decode2, _ := pem.Decode(b2.Bytes())
	key, err := smx509.ParsePKIXPublicKey(decode2.Bytes)
	if err != nil {
		panic(err)
	}
	pu = key.(*ecdsa.PublicKey)

	return
}

func req() {
	// 设置请求的URL
	url := "http://127.0.0.1:10000/hello"

	// 创建一个HTTP GET请求
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		fmt.Println("Error creating request:", err)
		return
	}

	// 发送请求
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error sending request:", err)
		return
	}
	defer resp.Body.Close()

	// 读取响应内容
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Error reading response body:", err)
		return
	}

	// 打印响应内容
	fmt.Println("Response Status:", resp.Status)
	fmt.Println("Response Body:", string(body))
}

//func PrivateEncode(deviceToken string) {
//	priKey, _ := ReadKeyFromFile(2)
//	// verifySM2Signature 模拟验证 SM2 签名的函数
//
//	PrivateKey, err := sm2.NewPrivateKey(priKey.D.Bytes())
//	if err != nil {
//		panic(err)
//	}
//	sign, err := PrivateKey.Sign(rand.Reader, deviceToken, sm2.DefaultSM2SignerOpts)
//}

func verifySM2Signature(PK *ecdsa.PublicKey, data, signature string) bool {
	// 在这里实现 SM2 签名的验证逻辑
	decodeString, err := hex.DecodeString(signature)
	if err != nil {
		panic(err)
	}
	return sm2.VerifyASN1WithSM2(PK, defaultUID, []byte(data), decodeString)
}
